#include "./math_test.h"

TEST(Radian, constructor_double) {

	// Arrange
	Radian *value1 = new Radian( pi/2.0 );

	// Act
	// Assert
	EXPECT_TRUE( value1 != NULL );
	EXPECT_EQ( (double)(*value1), pi/2.0 );

};

TEST(Radian, valid) {

	// Arrange
	Radian value1( 5.0*pi/2.0 ), final_value1( 5.0*pi/2.0 );
	Radian value2( pi/2.0 ), final_value2( pi/2.0 );
	double expected = value1.valid();

	// Act
	double actual = value2.valid();

	// Assert
	EXPECT_TRUE( value1 == final_value1 ) << "> value1: " << value1 << " | final_value1: " << final_value1 << pendl;
	EXPECT_TRUE( value2 == final_value2 ) << "> value2: " << value2 << " | final_value2: " << final_value2 << pendl;
	EXPECT_NEAR( expected, actual, 0.001 ) << "> expected: " << expected << " | actual: " << actual << pendl;

};

TEST(Radian, loops) {

	// Arrange
	Radian value1( 5.0*pi/2.0 ), final_value1( 5.0*pi/2.0 );
	double expected = 5.0/4.0;

	// Act
	double actual = value1.loops();

	// Assert
	EXPECT_TRUE( value1 == final_value1 ) << "> value1: " << value1 << " | final_value1: " << final_value1 << pendl;
	EXPECT_NEAR( expected, actual, 0.001 ) << "> expected: " << expected << " | actual: " << actual << pendl;

};

TEST(Radian, sin) {

	// Arrange
	Radian value1( pi/6.0 ), final_value1( pi/6.0 );
	double expected = sin( pi/6.0 );

	// Act
	double actual = value1.sin();

	// Assert
	EXPECT_TRUE( value1 == final_value1 ) << "> value1: " << value1 << " | final_value1: " << final_value1 << pendl;
	EXPECT_NEAR( expected, actual, 0.001 ) << "> expected: " << expected << " | actual: " << actual << pendl;

};

TEST(Radian, cos) {

	// Arrange
	Radian value1( pi/6.0 ), final_value1( pi/6.0 );
	double expected = cos( pi/6.0 );

	// Act
	double actual = value1.cos();

	// Assert
	EXPECT_TRUE( value1 == final_value1 ) << "> value1: " << value1 << " | final_value1: " << final_value1 << pendl;
	EXPECT_NEAR( expected, actual, 0.001 ) << "> expected: " << expected << " | actual: " << actual << pendl;

};

TEST(Radian, tan) {

	// Arrange
	Radian value1( pi/6.0 ), final_value1( pi/6.0 );
	double expected = tan( pi/6.0 );

	// Act
	double actual = value1.tan();

	// Assert
	EXPECT_TRUE( value1 == final_value1 ) << "> value1: " << value1 << " | final_value1: " << final_value1 << pendl;
	EXPECT_NEAR( expected, actual, 0.001 ) << "> expected: " << expected << " | actual: " << actual << pendl;

};

TEST(Radian, operatorEqual_Radian_Radian_true) {

	// Arrange
	Radian value1( pi/2.0 ), final_value1( pi/2.0 );
	Radian value2( pi/2.0 ), final_value2( pi/2.0 );
	bool expected = true;

	// Act
	bool actual = ( value1 == value2 );

	// Assert
	EXPECT_TRUE( value1 == final_value1 ) << "> value1: " << value1 << " | final_value1: " << final_value1 << pendl;
	EXPECT_TRUE( value2 == final_value2 ) << "> value2: " << value2 << " | final_value2: " << final_value2 << pendl;
	EXPECT_TRUE( expected == actual ) << "> expected: " << expected << " | actual: " << actual << pendl;

};

TEST(Radian, operatorEqual_Radian_Radian_false) {

	// Arrange
	Radian value1( pi/2.0 ), final_value1( pi/2.0 );
	Radian value2( 1.0 ), final_value2( 1.0 );
	bool expected = false;

	// Act
	bool actual = ( value1 == value2 );

	// Assert
	EXPECT_TRUE( value1 == final_value1 ) << "> value1: " << value1 << " | final_value1: " << final_value1 << pendl;
	EXPECT_TRUE( value2 == final_value2 ) << "> value2: " << value2 << " | final_value2: " << final_value2 << pendl;
	EXPECT_TRUE( expected == actual ) << "> expected: " << expected << " | actual: " << actual << pendl;

};

TEST(Radian, operatorNotEquals_Radian_Radian_true) {

	// Arrange
	Radian value1( pi ), final_value1( pi );
	Radian value2( pi/4.0 ), final_value2( pi/4.0 );
	bool expected = true;

	// Act
	bool actual = ( value1 != value2 );

	// Assert
	EXPECT_TRUE( value1 == final_value1 ) << "> value1: " << value1 << " | final_value1: " << final_value1 << pendl;
	EXPECT_TRUE( value2 == final_value2 ) << "> value2: " << value2 << " | final_value2: " << final_value2 << pendl;
	EXPECT_TRUE( expected == actual ) << "> expected: " << expected << " | actual: " << actual << pendl;

};

TEST(Radian, operatorNotEqual_Radian_Radian_false) {

	// Arrange
	Radian value1( pi/2.0 ), final_value1( pi/2.0 );
	Radian value2( pi/2.0 ), final_value2( pi/2.0 );
	bool expected = false;

	// Act
	bool actual = ( value1 != value2 );

	// Assert
	EXPECT_TRUE( value1 == final_value1 ) << "> value1: " << value1 << " | final_value1: " << final_value1 << pendl;
	EXPECT_TRUE( value2 == final_value2 ) << "> value2: " << value2 << " | final_value2: " << final_value2 << pendl;
	EXPECT_TRUE( expected == actual ) << "> expected: " << expected << " | actual: " << actual << pendl;

};

TEST(Radian, conversion_FromRadian_ToDouble) {

	// Arrange
	Radian value1( pi/2.0 ), final_value1( pi/2.0 );
	double expected = pi/2.0;

	// Act
	double actual = value1;

	// Assert
	EXPECT_TRUE( value1 == final_value1 ) << "> value1: " << value1 << " | final_value1: " << final_value1 << pendl;
	EXPECT_TRUE( expected == actual ) << "> expected: " << expected << " | actual: " << actual << pendl;

};

TEST(Radian, operatorAttribution_Radian) {

	// Arrange
	Radian value1( pi/2.0 ), final_value1( pi );
	Radian value2( pi/4.0 ), final_value2( pi/4.0 );
	Radian value3( pi ), final_value3( pi );
	Radian expected = pi;

	// Act
	Radian actual = ( ( value1 = value2 ) = value3 );

	// Assert
	EXPECT_TRUE( value1 == final_value1 ) << "> value1: " << value1 << " | final_value1: " << final_value1 << pendl;
	EXPECT_TRUE( value2 == final_value2 ) << "> value2: " << value2 << " | final_value2: " << final_value2 << pendl;
	EXPECT_TRUE( value3 == final_value3 ) << "> value3: " << value3 << " | final_value3: " << final_value3 << pendl;
	EXPECT_TRUE( expected == actual ) << "> expected: " << expected << " | actual: " << actual << pendl;

};

TEST(Radian, operatorAttribution_Double) {

	// Arrange
	Radian value1( pi/2.0 ), final_value1( pi );
	double expected = pi;

	// Act
	Radian actual = ( value1 = expected );

	// Assert
	EXPECT_TRUE( value1 == final_value1 ) << "> value1: " << value1 << " | final_value1: " << final_value1 << pendl;
	EXPECT_TRUE( expected == actual ) << "> expected: " << expected << " | actual: " << actual << pendl;

};

TEST(Radian, operatorAdditionAndAttribution_Radian) {

	// Arrange
	Radian value1( pi/2.0 ), final_value1( 7*pi/4.0 );
	Radian value2( pi ), final_value2( pi );
	Radian value3( pi/4.0 ), final_value3( pi/4.0 );
	Radian expected = 7*pi/4.0;

	// Act
	Radian actual = ( ( value1 += value2 ) += value3 );

	// Assert
	EXPECT_TRUE( value1 == final_value1 ) << "> value1: " << value1 << " | final_value1: " << final_value1 << pendl;
	EXPECT_TRUE( value2 == final_value2 ) << "> value2: " << value2 << " | final_value2: " << final_value2 << pendl;
	EXPECT_TRUE( value3 == final_value3 ) << "> value3: " << value3 << " | final_value3: " << final_value3 << pendl;
	EXPECT_TRUE( expected == actual ) << "> expected: " << expected << " | actual: " << actual << pendl;

};

TEST(Radian, operatorSubtractionAndAttribution_Radian) {

	// Arrange
	Radian value1( pi ), final_value1( pi/4.0 );
	Radian value2( pi/2.0 ), final_value2( pi/2.0 );
	Radian value3( pi/4.0 ), final_value3( pi/4.0 );
	Radian expected = pi/4.0;

	// Act
	Radian actual = ( ( value1 -= value2 ) -= value3 );

	// Assert
	EXPECT_TRUE( value1 == final_value1 ) << "> value1: " << value1 << " | final_value1: " << final_value1 << pendl;
	EXPECT_TRUE( value2 == final_value2 ) << "> value2: " << value2 << " | final_value2: " << final_value2 << pendl;
	EXPECT_TRUE( value3 == final_value3 ) << "> value3: " << value3 << " | final_value3: " << final_value3 << pendl;
	EXPECT_TRUE( expected == actual ) << "> expected: " << expected << " | actual: " << actual << pendl;

};

TEST(Radian, operatorMultiplicationAndAttribution_Double) {

	// Arrange
	Radian value1( pi/2.0 ), final_value1( 3.0*pi/2.0 );
	Radian expected = 3.0*pi/2.0;

	// Act
	Radian actual = ( ( value1 *= 2.0 ) *= 1.5 );

	// Assert
	EXPECT_TRUE( value1 == final_value1 ) << "> value1: " << value1 << " | final_value1: " << final_value1 << pendl;
	EXPECT_TRUE( expected == actual ) << "> expected: " << expected << " | actual: " << actual << pendl;

};

TEST(Radian, operatorDivisionAndAttribution_Double) {

	// Arrange
	Radian value1( pi ), final_value1( -pi/2.0 );
	Radian expected = -pi/2.0;

	// Act
	Radian actual = ( ( value1 /= 2.0 ) /= -1.0 );

	// Assert
	EXPECT_TRUE( value1 == final_value1 ) << "> value1: " << value1 << " | final_value1: " << final_value1 << pendl;
	EXPECT_TRUE( expected == actual ) << "> expected: " << expected << " | actual: " << actual << pendl;

};

TEST(Radian, operatorAddition_Double) {

	// Arrange
	Radian value1( pi/2.0 ), final_value1( pi/2.0 );
	Radian value2( pi ), final_value2( pi );
	Radian expected = pi + pi/2.0;

	// Act
	Radian actual = value1 + value2;

	// Assert
	EXPECT_TRUE( value1 == final_value1 ) << "> value1: " << value1 << " | final_value1: " << final_value1 << pendl;
	EXPECT_TRUE( value2 == final_value2 ) << "> value2: " << value2 << " | final_value2: " << final_value2 << pendl;
	EXPECT_TRUE( expected == actual ) << "> expected: " << expected << " | actual: " << actual << pendl;

};

TEST(Radian, operatorSubtraction_Double) {

	// Arrange
	Radian value1( pi/2.0 ), final_value1( pi/2.0 );
	Radian value2( pi ), final_value2( pi );
	Radian expected = pi/2.0 - pi;

	// Act
	Radian actual = value1 - value2;

	// Assert
	EXPECT_TRUE( value1 == final_value1 ) << "> value1: " << value1 << " | final_value1: " << final_value1 << pendl;
	EXPECT_TRUE( value2 == final_value2 ) << "> value2: " << value2 << " | final_value2: " << final_value2 << pendl;
	EXPECT_TRUE( expected == actual ) << "> expected: " << expected << " | actual: " << actual << pendl;

};

TEST(Radian, operatorMultiplication_Double) {

	// Arrange
	Radian value1( pi ), final_value1( pi );
	Radian expected = pi/2.0;

	// Act
	Radian actual = value1 * 0.5;

	// Assert
	EXPECT_TRUE( value1 == final_value1 ) << "> value1: " << value1 << " | final_value1: " << final_value1 << pendl;
	EXPECT_TRUE( expected == actual ) << "> expected: " << expected << " | actual: " << actual << pendl;

};

TEST(Radian, operatorDivision_Double) {

	// Arrange
	Radian value1( pi/2.0 ), final_value1( pi/2.0 );
	Radian expected = pi/4.0;

	// Act
	Radian actual = value1 / 2.0;

	// Assert
	EXPECT_TRUE( value1 == final_value1 ) << "> value1: " << value1 << " | final_value1: " << final_value1 << pendl;
	EXPECT_TRUE( expected == actual ) << "> expected: " << expected << " | actual: " << actual << pendl;

};

TEST(Radian, convert_fromRadian_toDegree) {

	// Arrange
	Radian value1( pi/2.0 ), final_value1( pi/2.0 );
	Degree expected( 90.0 );

	// Act
	Degree actual = value1;

	// Assert
	EXPECT_TRUE( value1 == final_value1 ) << "> value1: " << value1 << " | final_value1: " << final_value1 << pendl;
	EXPECT_TRUE( expected == actual ) << "> expected: " << expected << " | actual: " << actual << pendl;

};

TEST(Radian, convert_fromDegree_toRadian) {

	// Arrange
	Degree value1( 30.0 ), final_value1( 30.0 );
	Radian expected( pi/6.0 );

	// Act
	Radian actual = value1;

	// Assert
	EXPECT_TRUE( value1 == final_value1 ) << "> value1: " << value1 << " | final_value1: " << final_value1 << pendl;
	EXPECT_TRUE( expected == actual ) << "> expected: " << expected << " | actual: " << actual << pendl;

};

TEST(Radian, convert_fromRadian_toGrade) {

	// Arrange
	Radian value1( pi/2.0 ), final_value1( pi/2.0 );
	Grade expected( 100.0 );

	// Act
	Grade actual = value1;

	// Assert
	EXPECT_TRUE( value1 == final_value1 ) << "> value1: " << value1 << " | final_value1: " << final_value1 << pendl;
	EXPECT_TRUE( expected == actual ) << "> expected: " << expected << " | actual: " << actual << pendl;

};

TEST(Radian, convert_fromGrade_toRadian) {

	// Arrange
	Grade value1( 50.0 ), final_value1( 50.0 );
	Radian expected( pi/4.0 );

	// Act
	Radian actual = value1;

	// Assert
	EXPECT_TRUE( value1 == final_value1 ) << "> value1: " << value1 << " | final_value1: " << final_value1 << pendl;
	EXPECT_TRUE( expected == actual ) << "> expected: " << expected << " | actual: " << actual << pendl;

};

